<!-- components/custom-upload.vue -->
<template>
  <view class="custom-upload">
    <!-- 图片预览列表 -->
    <view class="preview-list">
      <view
        v-for="(item, index) in innerFileList"
        :key="item.uid"
        class="preview-item"
      >
        <image
          :src="item.url"
          mode="aspectFill"
          class="preview-image"
          @click="handlePreview(index)"
          @longpress="handleLongPress(index)"
        />
        <view class="file-status">
          <!-- 上传进度 -->
          <progress
            v-if="item.status === 'uploading'"
            :percent="item.progress"
            class="progress-bar"
          />
          <!-- 失败提示 -->
          <text v-if="item.status === 'error'" class="status-text error"
            >上传失败</text
          >
          <!-- 成功标识 -->
          <text v-if="item.status === 'success'" class="status-text success"
            >✓</text
          >
        </view>
        <!-- 删除按钮 -->
        <view
          class="delete-btn"
          @click.stop="handleDelete(index)"
          v-if="!disabled"
        >
          <text class="delete-icon">×</text>
        </view>
      </view>

      <!-- 上传按钮 -->
      <view
        v-if="showUploadButton && !disabled"
        class="upload-btn"
        @click="triggerUpload"
      >
        <u-icon
          size="30"
          name="camera"
          color="#c8c9cc"
        ></u-icon>
      </view>
    </view>

    <!-- 微信长按操作菜单 -->
    <!-- <uni-popup ref="actionSheet" type="dialog">
      <view class="action-sheet">
        <view class="action-item" @click="saveCurrentImage">保存到相册</view>
        <view class="action-item" @click="shareCurrentImage">分享</view>
        <view class="action-item cancel" @click="closeActionSheet">取消</view>
      </view>
    </uni-popup> -->
    <mytoast ref="toastRef" />
  </view>
</template>

<script>
let uid = 0;
import mytoast from "@/components/mytoast.vue";
import store from "@/store/index.js";
export default {
  name: "customUpload",
  components: {
    mytoast,
  },

  props: {
    value: {
      type: Array,
      default: () => [],
    },
    maxCount: {
      type: Number,
      default: 9,
    },
    multiple: {
      type: Boolean,
      default: true,
    },
    // 上传接口配置
    action: {
      type: String,
      required: true,
      default: "/Upload/uploadFile",
    },
    // 额外参数
    data: {
      type: Object,
      default: () => ({}),
    },
    // 文件字段名
    name: {
      type: String,
      default: "file",
    },
    size: {
      type: Number,
      default: 1024 * 1024 * 10,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },

  data() {
    return {
      innerFileList: [],
      currentPreviewIndex: -1,
      // baseUrl: "http://8.138.214.11:8888/api/Upload/uploadFile",
      // baseUrl: "http://192.168.110.185:5003/api/Upload/uploadFile",
      baseUrl: "https://www.yinyaoit.com/api/Upload/uploadFile",
      imgUrl: "https://www.yinyaoit.com",
      // imgUrl: "http://192.168.110.32:8888",
    };
  },
  computed: {
    showUploadButton() {
      return this.innerFileList.length < this.maxCount;
    },
    imgLink() {
      return store.state.imgUrl;
    },
    imgUploadUrl() {
      return store.state.imgUploadUrl;
    },
  },
  watch: {
    value: {
      immediate: true,
      handler(newVal) {
        this.innerFileList = this.normalizeFiles(newVal);
        console.log(this.innerFileList, "innerFileList");
      },
    },
  },
  onShow() {
    // #ifdef MP-WEIXIN
    this.checkWxPermission().catch(() => {});
    // #endif
  },
  methods: {
    // 标准化文件数据
    normalizeFiles(list) {
      return list.map((item) => ({
        uid: uid++,
        url: item.url,
        status: "success",
        progress: 100,
        ...item,
      }));
    },

    // 触发上传
    async triggerUpload() {
      let that = this;
      try {
        const availableCount = this.maxCount - this.innerFileList.length;
        if (availableCount <= 0) {
          return uni.showToast({
            title: `最多上传${this.maxCount}个文件`,
            icon: "none",
          });
        }

        // 微信权限处理
        if (uni.getSystemInfoSync().platform === "devtools") {
          await this.checkWxPermission();
        }

        // 选择文件
        const { tempFiles } = await wx.chooseMedia({
          count: this.multiple ? Math.min(availableCount, 9) : 1,
          sizeType: ["original", "compressed"],
          sourceType: ["album", "camera"],
          mediaType: ["image"],
        });

        // 添加到上传队列
        const newFiles = tempFiles.map((file) => {
          console.log(this.size, file.size);

          console.log(file);
          if (file.size > that.size) {
            that.$refs.toastRef.showToast({
              msg: "图片大小不能超过" + that.size / 1024 / 1024 + "M",
              duration: 2000,
              position: "center",
            });
            throw Error("图片大小不能超过" + that.size / 1024 / 1024 + "M");
          }
          return {
            uid: uid++,
            url: file.tempFilePath,
            status: "uploading",
            progress: 0,
            rawFile: file,
          };
        });
        console.log(newFiles);

        this.innerFileList = [...this.innerFileList, ...newFiles];
        this.$emit("input", this.innerFileList);

        // 开始上传
        this.uploadFiles(newFiles);
      } catch (error) {
        this.handleError(error);
      }
    },

    async checkWxPermission() {
      // 确保只在微信环境执行
      // #ifdef MP-WEIXIN
      try {
        const { authSetting } = await wx.getSetting();
        console.log("当前权限设置:", authSetting);

        // 兼容处理未获取到authSetting的情况
        const hasPermission =
          authSetting && authSetting["scope.writePhotosAlbum"] === true;

        if (hasPermission) return;

        // 请求权限
        await wx.authorize({
          scope: "scope.writePhotosAlbum",
          fail: (err) => {
            console.log("授权失败:", err);
            if (err.errMsg.includes("auth deny")) {
              this.showAuthSettingGuide();
            }
          },
        });

        // 再次验证权限状态
        const { authSetting: newAuthSetting } = await wx.getSetting();
        if (!newAuthSetting["scope.writePhotosAlbum"]) {
          throw new Error("用户未授权相册权限");
        }
      } catch (error) {
        console.error("权限检查异常:", error);
        // if (error.errMsg?.includes("auth")) {
        this.showAuthSettingGuide();
        // }
        throw error;
      }
      // #endif
    },
    showAuthSettingGuide() {
      uni.showModal({
        title: "需要相册权限",
        content: "请前往设置页面开启相册访问权限",
        success: (res) => {
          if (res.confirm) {
            uni.openSetting();
          }
        },
      });
    },

    // 执行文件上传
    async uploadFiles(files) {
      let that = this;
      try {
        const uploadTasks = files.map((file) => {
          return new Promise((resolve, reject) => {
            const task = uni.uploadFile({
              url: this.imgUploadUrl,
              filePath: file.url,
              name: "form",
              success: (res) => {
                console.log(res);

                if (res.statusCode === 200) {
                  resolve({
                    uid: file.uid,
                    url: that.imgLink + "/" + res.data,
                    path: res.data,
                    status: "success",
                  });
                } else {
                  reject(new Error("上传失败"));
                }
              },
              fail: (err) => {
                console.log(err);

                reject(err);
              },
            });

            // 更新上传进度
            task.onProgressUpdate = (e) => {
              this.updateFileProgress(file.uid, e.progress);
            };
          });
        });

        const results = await Promise.all(uploadTasks);
        this.updateFileStatus(results);
      } catch (error) {
        console.log(error);

        this.updateFileStatus([], error);
      }
    },

    // 更新文件进度
    updateFileProgress(uid, progress) {
      this.innerFileList = this.innerFileList.map((file) =>
        file.uid === uid ? { ...file, progress } : file
      );
      this.$emit("input", this.innerFileList);
    },

    // 更新文件状态
    updateFileStatus(results, error) {
      this.innerFileList = this.innerFileList.map((file, index) => {
        console.log(results);

        const result = results.find((r) => r.uid === file.uid);
        if (result) {
          return { ...file, ...result };
        }
        if (error) {
          this.handleDelete(index);
          return { ...file, status: "error" };
        }
        return file;
      });
      this.$emit("input", this.innerFileList);
      this.$emit("change", this.innerFileList);
    },

    // 图片预览
    handlePreview(index) {
      console.log(this.imgLink);

      const validFiles = this.innerFileList.filter(
        (f) => f.status === "success"
      );
      console.log(validFiles, index);

      uni.previewImage({
        current: validFiles[index].url,
        urls: validFiles.map((f) => f.url),
      });
    },

    // 长按操作
    handleLongPress(index) {
      this.currentPreviewIndex = index;
      this.$refs.actionSheet.open();
    },

    // 保存图片到相册
    async saveCurrentImage() {
      const file = this.innerFileList[this.currentPreviewIndex];
      try {
        await uni.saveImageToPhotosAlbum({
          filePath: file.url,
        });
        uni.showToast({ title: "保存成功" });
      } catch (error) {
        uni.showToast({ title: "保存失败", icon: "none" });
      }
      this.closeActionSheet();
    },

    // 分享图片（示例）
    shareCurrentImage() {
      const file = this.innerFileList[this.currentPreviewIndex];
      uni.share({
        type: "image",
        imageUrl: file.url,
        success: () => {
          uni.showToast({ title: "分享成功" });
        },
      });
      this.closeActionSheet();
    },

    // 关闭操作菜单
    closeActionSheet() {
      this.$refs.actionSheet.close();
      this.currentPreviewIndex = -1;
    },

    // 删除文件
    handleDelete(index) {
      this.innerFileList.splice(index, 1);
      this.$emit("input", this.innerFileList);
      this.$emit("change", this.innerFileList);
    },

    // 错误处理
    handleError(error) {
      console.error("Upload Error:", error);
      let msg = error.errMsg;
      if (error.errMsg === "chooseMedia:fail cancel") {
        msg = "取消上传";
      }
      uni.showToast({
        title: msg || "操作失败",
        icon: "none",
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.custom-upload {
  padding: 20rpx;
  background-color: #fff;
}

.preview-list {
  display: flex;
  flex-wrap: wrap;
  margin: -10rpx;
}

.preview-item,
.upload-btn {
  width: 150rpx;
  height: 150rpx;
  margin: 10rpx;
  border-radius: 12rpx;
  position: relative;
  overflow: hidden;
  background-color: #f8f8f8;
}

.preview-image {
  width: 100%;
  height: 100%;
}

.upload-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border: 2rpx dashed #ddd;
  transition: all 0.3s;

  &:active {
    background-color: #f0f0f0;
  }
}

.plus-icon {
  font-size: 48rpx;
  color: #666;
  line-height: 1;
}

.btn-text {
  font-size: 26rpx;
  color: #888;
  margin-top: 10rpx;
}

.file-status {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 16rpx;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.6));
}

.progress-bar {
  width: 100%;
  transform: scaleY(0.6);
}

.status-text {
  position: absolute;
  right: 20rpx;
  bottom: 20rpx;
  font-size: 32rpx;
  color: #fff;

  &.error {
    color: #ff4d4f;
  }

  &.success {
    color: #4cd964;
  }
}

.delete-btn {
  position: absolute;
  top: 0;
  right: 0;
  width: 50rpx;
  height: 50rpx;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0 0 0 12rpx;
}

.delete-icon {
  color: #fff;
  font-size: 40rpx;
  line-height: 1;
  margin-top: -4rpx;
}

.action-sheet {
  background: #fff;
  border-radius: 24rpx;
  overflow: hidden;
  padding: 20rpx 0;
}

.action-item {
  padding: 30rpx;
  text-align: center;
  font-size: 32rpx;
  color: #333;
  border-bottom: 1rpx solid #eee;

  &:active {
    background-color: #f8f8f8;
  }

  &.cancel {
    color: #666;
    margin-top: 20rpx;
    border-top: 1rpx solid #eee;
    border-bottom: none;
  }
}
</style>
